package cn.wegoteam.shop.service;

import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.annotation.Resource;

import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import cn.wegoteam.shop.cache.Cache;
import cn.wegoteam.shop.inter.BaseDaoInter;
import cn.wegoteam.shop.inter.CartServiceInter;
import cn.wegoteam.shop.inter.OrderServiceInter;
import cn.wegoteam.shop.inter.UserServiceInter;
import cn.wegoteam.shop.po.Address;
import cn.wegoteam.shop.po.Cart;
import cn.wegoteam.shop.po.Order;
import cn.wegoteam.shop.po.Staticdata;
import cn.wegoteam.shop.po.User;
import cn.wegoteam.shop.util.Const;
import cn.wegoteam.shop.util.DateFormartUtil;
import cn.wegoteam.shop.util.MyString;

@Service
public class OrderService extends BaseService<Order> implements
		OrderServiceInter {
	@Resource
	private UserServiceInter userService;
	@Override
	@Transactional(propagation = Propagation.REQUIRED)
	public boolean save(Order model,User user,CartServiceInter cartService,Map<String,Object> session,StringBuilder sb,Address ad) {
		if(ad==null||!ad.getUser().getId().equals(user.getId()))
			return false;
		
		model.setAccepter(ad.getAccepter());
		model.setAddress(ad.getSubarea()+"——"+ad.getDetailAddress());
		model.setPhone(ad.getPhone());
		model.setTelephone(ad.getTelephone());
		@SuppressWarnings("unchecked")
		List<Cart> cs=(List<Cart>) session.get(Const.SESS_ORDERS);
		model.setUser(user);
		model.setOrderNumber(DateFormartUtil.getDateByFormat("yyMMddHHmmssSSS")+"_"+user.getId());
		model.setPostcode(ad.getPostcode());
		
		super.save(model);
		float total = 0.0f;
		for(Cart c:cs){
			c.setOrder(model);
			cartService.save(c);
			sb.append(c.getProduct().getId()+",");
			total += c.getNum()*c.getProduct().getTruePrice();
			//更新商品剩余量，销量
			//剩余量可以为负数，因为多个用户同时支付或商品已经在订单中但是没有支付，可能出现剩余量为空的情况
			cartService.executeByHql(
						"update Product set remainder=remainder-"+c.getNum()+",sellNum=sellNum+"+c.getNum()+" where id="+c.getProduct().getId(),null);
		}
		//state,flage不可插入，因此保存后model中为空，因此必须赋值
		if(total>Float.parseFloat(Cache.getSetting(Const.FREEOFLOGISTICS).getValue())){
			model.setFreight(0.0F);
		}
		model.setFlag(1);
		model.setState(Const.STATIC_UNPAY);
		model.setTotal(total);
		
		user = userService.get(user);
		//如果使用的积分大于用户的积分，则设置为用户的积分
		if(model.getBounds()>user.getBounds())
			model.setBounds(user.getBounds());
		//如果使用的积分大于商品总价值，则设置为商品的价值
		Float jifen = model.getBounds()/Float.parseFloat(Cache.getSetting(Const.JIFEN).getValue());
		if(jifen>model.getTotal()+model.getFreight())
		{
			model.setBounds((int)((model.getTotal()+model.getFreight())*Integer.parseInt(Cache.getSetting(Const.JIFEN).getValue())));
		}
		user.setBounds(user.getBounds()-model.getBounds());
		userService.update(user);
		session.put(Const.SESS_USER, user);
		update(model);
		return true;
	}
	@Override
	public String modifyOrder(Order model,User user,int flag,String state){
		model=this.get(model);
		//非法修改不是自己的订单信息
		if(!model.getUser().getId().equals(user.getId())){
			return "非法操作！操作失败";
		}
		if(state.equals("")&&flag==0){
			return "非法操作！操作失败";
		}
		List<Staticdata> sds = model.getOperates();
		boolean isLegal = false;
		
		if(state.equals("")){
			//删除订单
			//判断当前操作是否合法
			isLegal = isLegal(sds, isLegal,"p_flag=-1");
			if(!isLegal){
				return "非法操作！操作失败";
			}
			model.setFlag(-1);
		}
		else
		{
			//判断当前操作是否合法
			isLegal = isLegal(sds, isLegal,"p_state="+state);
			if(!isLegal){
				return "非法操作！操作失败";
			}
			if(model.getState().equals(state)){
				return "非法操作！操作失败";
			}
			model.setState(state);
		}
		update(model);
		
		//返回积分至用户账号中
		if(state.equals(Const.STATIC_CANCEL)){
			userService.executeByHql("update User set bounds=bounds+"+model.getBounds()+" where id="+user.getId(), null);
			user.setBounds(user.getBounds()+model.getBounds());
		}
		//恢复库存及销量
		for(Cart c:model.getCarts())
			executeByHql(
					"update Product set remainder=remainder+"+c.getNum()+",sellNum=sellNum-"+c.getNum()+" where id="+c.getProduct().getId(),null);
		
		//清除可操作的action
		model.clearOperates();
		return null; 
	}
	/**
	 * 从staticdata表中根据当前状态获取可操作的action
	 * 查询当前请求是否在action中
	 * @param sds
	 * @param isLegal
	 * @param link
	 * @return
	 */
	private boolean isLegal(List<Staticdata> sds, boolean isLegal,String link) {
		for(Staticdata sd:sds){
			if(sd.getLink().contains(link)){
				isLegal = true;
				break;
			}
		}
		return isLegal;
	}
	@Override
	public int updateBySql(Order o){
		if(o.getId()==null)
			return 0;
		Map<String, Object> map = new HashMap<String, Object>();
		StringBuilder sql=new StringBuilder("UPDATE torder SET id=id ");
		if(!MyString.isEmpty(o.getAccepter())){
			sql.append(",accepter=:accepter");
			map.put("accepter",o.getAccepter());
		}
		if(!MyString.isEmpty(o.getAddress())){
			sql.append(",address=:address");
			map.put("address",o.getAddress());
		}
		if(!MyString.isEmpty(o.getLogistics())){
			sql.append(",logistics=:logistics");
			map.put("logistics",o.getLogistics());
		}
		if(!MyString.isEmpty(o.getLogisticsNum())){
			sql.append(",logisticsNum=:logisticsNum");
			map.put("logisticsNum",o.getLogisticsNum());
		}
		if(!MyString.isEmpty(o.getMessage())){
			sql.append(",message=:message");
			map.put("message",o.getMessage());
		}
		if(!MyString.isEmpty(o.getPhone())){
			sql.append(",phone=:phone");
			map.put("phone",o.getPhone());
		}
		if(!MyString.isEmpty(o.getPostcode())){
			sql.append(",postcode=:postcode");
			map.put("postcode",o.getPostcode());
		}
		if(!MyString.isEmpty(o.getState())){
			sql.append(",state=:state");
			map.put("state",o.getState());
		}
		if(!MyString.isEmpty(o.getTelephone())){
			sql.append(",telephone=:telephone");
			map.put("telephone",o.getTelephone());
		}
		if(!MyString.isEmpty(o.getTotal()+"")){
			sql.append(",total=:total");
			map.put("total",o.getTotal());
		}
		if(!MyString.isEmpty(o.getFreight()+"")){
			sql.append(",freight=:freight");
			map.put("freight",o.getFreight());
		}
		
		sql.append(" WHERE id="+o.getId());	
		return super.executeBySql(sql.toString(),map);
	}
	@Resource(name="orderDao")
	public void setBaseDao(BaseDaoInter<Order> baseDao) {
		super.setBaseDao(baseDao);
	}
	
}
